/*
 * main.cpp
 *
 *  Created on: 2010-9-2
 *      Author: liuyi
 */

#include <iostream>
#include <cxcore.h>
#include <cv.h>
#include <highgui.h>

#include "Debug.h"

using namespace std;

#define unsigned char uchar

const static int normWidth = 600;
const static int normHeight = 400;

const static int RGB_CHANNAL = 3;

void test0(const char *filename) {
	IplImage *rgb = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR);

	if (rgb->width > normWidth && rgb->height > normHeight) {
		IplImage *disp = cvCreateImage(cvSize(normWidth, normHeight),
				IPL_DEPTH_8U, RGB_CHANNAL);
		cvResize(rgb, disp);
		Debug::showImage("origin", disp);

		cvReleaseImage(&disp);
	} else {
		Debug::showImage("origin", rgb);
	}

	cvReleaseImage(&rgb);
}

void test1(const char *filename) {
	IplImage *rgb = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR);

	int width = rgb->width;
	int height = rgb->height;

	IplImage *hsv = cvCreateImage(cvGetSize(rgb), IPL_DEPTH_8U, RGB_CHANNAL);
	cvCvtColor(rgb, hsv, CV_BGR2HSV);

	uchar *data = (uchar *) hsv->imageData;
	int widthStep = hsv->widthStep;
	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			if (data[widthStep * i + RGB_CHANNAL * j + 1] == 0) {
				continue;
			}

			data[widthStep * i + RGB_CHANNAL * j + 1] = 255;
			data[widthStep * i + RGB_CHANNAL * j + 2] = 255;
		}
	}

	cvCvtColor(hsv, rgb, CV_HSV2BGR);

	Debug::showManyImage("test", 1, rgb);

	cvReleaseImage(&rgb);
	cvReleaseImage(&hsv);
}

void test2(const char *filename) {
	IplImage *src = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR);

	int width = src->width;
	int height = src->height;

	IplImage *dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, RGB_CHANNAL);
	cvCopy(src, dst);

	uchar *data = (uchar *) dst->imageData;
	int widthStep = dst->widthStep;
	uchar *p = NULL;
	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			p = data + widthStep * i + RGB_CHANNAL * j;

			if(*p < *(p + 1)) {
				*p = 0;

				if(*(p + 1) < *(p + 2)) {
					*(p + 1) = 0;
				} else {
					*(p + 2) = 0;
				}
			} else {
				*(p + 1) = 0;

				if(*p < *(p + 2)) {
					*p = 0;
				} else {
					*(p + 2) = 0;
				}
			}
		}
	}

	Debug::showManyImage("test", 2, src, dst);

	cvReleaseImage(&src);
	cvReleaseImage(&dst);
}

// split r, g, b
void test3(const char *filename) {
	IplImage *src = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR);

	IplImage *r = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *g = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *b = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);

	cvSplit(src, b, g, r, NULL);

	IplImage *disp = cvCreateImage(cvSize(600, 400), IPL_DEPTH_8U, 1);

	cvResize(r, disp);
	Debug::showImage("red", disp);
	cvResize(g, disp);
	Debug::showImage("green", disp);
	cvResize(b, disp);
	Debug::showImage("blue", disp);

	cvReleaseImage(&disp);
	cvReleaseImage(&src);
	cvReleaseImage(&r);
	cvReleaseImage(&g);
	cvReleaseImage(&b);
}

// split max, mid, min
void test4(const char *filename) {
	IplImage *src = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR);

	int width = src->width;
	int height = src->height;

	uchar *srcData = (uchar *) src->imageData;
	int srcStep = src->widthStep;

	IplImage *max = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *mid = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
	IplImage *min = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);

	uchar *maxData = (uchar *) max->imageData;
	uchar *midData = (uchar *) mid->imageData;
	uchar *minData = (uchar *) min->imageData;
	int dstStep = max->widthStep;

	uchar *p = NULL;
	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			p = srcData + srcStep * i + RGB_CHANNAL * j;

			if (*p < *(p + 1)) {
				if (*(p + 1) < *(p + 2)) {
					*(maxData + dstStep * i + j) = *(p + 2);
					*(midData + dstStep * i + j) = *(p + 1);
					*(minData + dstStep * i + j) = *p;
				} else {
					*(maxData + dstStep * i + j) = *(p + 1);

					if (*p < *(p + 2)) {
						*(midData + dstStep * i + j) = *(p + 2);
						*(minData + dstStep * i + j) = *p;
					} else {
						*(midData + dstStep * i + j) = *p;
						*(minData + dstStep * i + j) = *(p + 2);
					}
				}
			} else {
				if (*p < *(p + 2)) {
					*(maxData + dstStep * i + j) = *(p + 2);
					*(midData + dstStep * i + j) = *p;
					*(minData + dstStep * i + j) = *(p + 1);
				} else {
					*(maxData + dstStep * i + j) = *p;

					if (*(p + 1) < *(p + 2)) {
						*(midData + dstStep * i + j) = *(p + 2);
						*(minData + dstStep * i + j) = *(p + 1);
					} else {
						*(midData + dstStep * i + j) = *(p + 1);
						*(minData + dstStep * i + j) = *(p + 2);
					}
				}
			}
		}
	}

	IplImage *disp = cvCreateImage(cvSize(normWidth, normHeight), IPL_DEPTH_8U, 1);

	cvResize(max, disp);
	Debug::showImage("max", disp);
	cvResize(mid, disp);
	Debug::showImage("mid", disp);
	cvResize(min, disp);
	Debug::showImage("min", disp);

	cvReleaseImage(&disp);
	cvReleaseImage(&src);
	cvReleaseImage(&max);
	cvReleaseImage(&mid);
	cvReleaseImage(&min);
}

int main(int argc, char **argv) {
	const char *filename = "data/image/(2).jpg";

	test0(filename);
}
